//
//  AESSecurityTool.m
//  AESSecurity
//
//  Created by  on 15/11/26.
//  Copyright © 2015年 caocaosong. All rights reserved.
//

#import "AESSecurityTool.h"
#import <CommonCrypto/CommonCryptor.h>
#import "Base64.h"


#define ENCRYPT_ALGORITHM     kCCAlgorithmAES128
#define ENCRYPT_BLOCK_SIZE    kCCBlockSizeAES128
#define ENCRYPT_KEY_SIZE      kCCKeySizeAES128

@implementation AESSecurityTool


//保存在属性列表中
+ (BOOL)saveAESKeyWithString:(NSString *)string
{
    if (string && string.length) {
        UserSetValueForKey(string, @"AESKey");
        return YES;
    }
    return NO;
}
//判断是否存在
+ (BOOL)canImportKey
{
    
    if (UserValue(@"AESKey")) {
        return YES;
    }
    return NO;
}

//删除当前属性列中的选项
+ (BOOL)removeAESKey {
    if(UserValue(@"AESKey")) {
        [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"AESKey"];
        return YES;
    }
    return NO;
}

+ (NSData *)encryptAndBase64ToDataWithString:(NSString *)str
{
    NSData *keyData = [UserValue(@"AESKey") dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data_aes = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding]
                                     key:keyData];
    
    return [[NSString stringWithFormat:@"%@",[Base64 stringByEncodingData:data_aes]] dataUsingEncoding:NSUTF8StringEncoding];
}


+ (NSString *)encryptAndBase64ToStringWithString:(NSString *)str
{
    NSData *keyData = [UserValue(@"AESKey") dataUsingEncoding:NSUTF8StringEncoding];
    
    NSData *data_aes = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding]
                                     key:keyData];
    
    
    return [NSString stringWithFormat:@"%@",[Base64 stringByEncodingData:data_aes]];
    
}


+ (NSString *)decryptAndBase64ToStringWithString:(NSString *)str
{
    NSData *keyData = [UserValue(@"AESKey") dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data_dec = [self decryptData:[Base64 decodeString:str]
                                     key:keyData];
    
    return [[NSString alloc]initWithData:data_dec encoding:NSUTF8StringEncoding];
    
}


+ (NSData *)decryptAndBase64ToDataWithString:(NSString *)str
{    NSData *keyData = [UserValue(@"AESKey") dataUsingEncoding:NSUTF8StringEncoding];
    return [self decryptData:[Base64 decodeString:str]
                         key:keyData];
}




# pragma mark- AES加密解密底层调用的方法，不需要直接调用。
+ (NSData*)encryptData:(NSData*)data key:(NSData*)key;
{
    NSData* result = nil;
    
    // 设置密钥数组
    unsigned char cKey[ENCRYPT_KEY_SIZE];
    bzero(cKey, sizeof(cKey));
    [key getBytes:cKey length:ENCRYPT_KEY_SIZE];
    
    // 设置输出的数据
    size_t bufferSize = [data length] + ENCRYPT_BLOCK_SIZE;
    void *buffer = malloc(bufferSize);
    
    // 开始加密
    size_t encryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          ENCRYPT_ALGORITHM,
                                          kCCOptionECBMode|kCCOptionPKCS7Padding,
                                          cKey,
                                          ENCRYPT_KEY_SIZE,
                                          nil,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &encryptedSize);
    if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
    } else {
        free(buffer);
        NSLog(@"[ERROR] failed to encrypt|CCCryptoStatus: %d", cryptStatus);
    }
    
    return result;
}

+ (NSData*)decryptData:(NSData*)data key:(NSData*)key;
{
    NSData* result = nil;
    
    // 设置密钥
    unsigned char cKey[ENCRYPT_KEY_SIZE];
    bzero(cKey, sizeof(cKey));
    [key getBytes:cKey length:ENCRYPT_KEY_SIZE];
    
    // 设置输出数据
    size_t bufferSize = [data length] + ENCRYPT_BLOCK_SIZE;
    void *buffer = malloc(bufferSize);
    
    // 开始解密
    size_t decryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          ENCRYPT_ALGORITHM,
                                          kCCOptionECBMode|kCCOptionPKCS7Padding,
                                          cKey,
                                          ENCRYPT_KEY_SIZE,
                                          nil,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &decryptedSize);
    
    if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
    } else {
        free(buffer);
        NSLog(@"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
    }
    
    return result;
}


@end
